using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ctsu.Admin.Forms;
using ctsu.BaseForms;
using ctsu.Data;
using ctsu.Security;
using ctsu.Shared;

using Syncfusion.Windows.Forms.Tools;

namespace ctsu.Admin.BusLogic
{
	public class BLFormAncillaryOutPatientImpl : BLFormBaseImpl
	{
		private bool _bIgnoreChargeEvents = false;
		enum SearchTypes { Standard, OutpatientVisits, Patient, Protocol, Investigator };
		private SearchTypes _searchType = SearchTypes.Standard;
		#region control references
		private Syncfusion.Windows.Forms.Tools.DateTimePickerAdv _testDate;
		private TextBox _visit;
		private TextBox _visitDate;
		private TextBox _category;
		private TextBox _patient;
		private TextBox _mrn;
		private TextBox _patientName;
		private Button _btnPatient;
		private Button _btnProtocol;
		private Button _btnVisit;
		private TextBox _protocol;
		//private TextBox _spid;
		private TextBox _protocolNumber;
		private TextBox _investigator;
		private TextBox _rate;
		private TextBox _charge;
		private TextBox _netCost;
		private TextBox _reference;
		private TextBox _labTests;
		private RadioButton _rdoGross;
		private RadioButton _rdoNet;
		private ComboBox _costCenter;
		private ComboBox _ancillarySource;
		#endregion control references

		#region construct & initialize
		public BLFormAncillaryOutPatientImpl(FormMain formMain, FormBase form, FormInfoBase formInfo, DataTable tableSchema, Permission formSecurity, Hashtable configData)
			: base(formMain, form, formInfo, tableSchema, formSecurity, configData)
		{

		}

		protected override void _vcManager_OnAfterHookEvents()
		{
			_testDate = (DateTimePickerAdv)Forms.Utils.GetControlByName("TestDate", this._form.Controls);
			_visit = (TextBox)Forms.Utils.GetControlByName("Visit", this._form.Controls);
			_visitDate = (TextBox)Forms.Utils.GetControlByName("VisitDate", this._form.Controls);
			_category = (TextBox)Forms.Utils.GetControlByName("Category", this._form.Controls);
			_patient = (TextBox)Forms.Utils.GetControlByName("Patient", this._form.Controls);
			_mrn = (TextBox)Forms.Utils.GetControlByName("MRN", this._form.Controls);
			_patientName = (TextBox)Forms.Utils.GetControlByName("PatientName", this._form.Controls);
			_btnPatient = (Button)Forms.Utils.GetControlByName("btnPatient", this._form.Controls);
			_btnProtocol = (Button)Forms.Utils.GetControlByName("btnProtocol", this._form.Controls);
			_btnVisit = (Button)Forms.Utils.GetControlByName("btnVisit", this._form.Controls);
			_protocol = (TextBox)Forms.Utils.GetControlByName("Protocol", this._form.Controls);
			//_spid = (TextBox)Forms.Utils.GetControlByName("SPID", this._form.Controls);
			_protocolNumber = (TextBox)Forms.Utils.GetControlByName("ProtocolNumber", this._form.Controls);
			_investigator = (TextBox)Forms.Utils.GetControlByName("Investigator", this._form.Controls);
			_rate = (TextBox)Forms.Utils.GetControlByName("Rate", this._form.Controls);
			_charge = (TextBox)Forms.Utils.GetControlByName("Charge", this._form.Controls);
			_netCost = (TextBox)Forms.Utils.GetControlByName("NetCost", this._form.Controls);
			_reference = (TextBox)Forms.Utils.GetControlByName("Reference", this._form.Controls);
			_labTests = (TextBox)Forms.Utils.GetControlByName("LabTests", this._form.Controls);

			_labTests.KeyPress += new KeyPressEventHandler(Forms.Utils.txtNumWholePos_KeyPress);
			_netCost.Validating += new CancelEventHandler(this.ChargeAndNetCost_Validating);
			_charge.Validating += new CancelEventHandler(this.ChargeAndNetCost_Validating);
			_netCost.KeyPress += new KeyPressEventHandler(Forms.Utils.txtNumDecNeg_KeyPress);
			_charge.KeyPress += new KeyPressEventHandler(Forms.Utils.txtNumDecNeg_KeyPress);

			_rdoGross = (RadioButton)Forms.Utils.GetControlByName("rdoGross", this._form.Controls);
			_rdoNet = (RadioButton)Forms.Utils.GetControlByName("rdoNet", this._form.Controls);
			_costCenter = (ComboBox)Forms.Utils.GetControlByName("CostCenter", this._form.Controls);

			_costCenter.SelectedIndexChanged += new EventHandler(_costCenter_SelectedIndexChanged);
			_ancillarySource = (ComboBox)Forms.Utils.GetControlByName("AncillarySource", this._form.Controls);

			_rdoGross.CheckedChanged += new EventHandler(rdoCalc_CheckedChanged);
			_rdoNet.CheckedChanged += new EventHandler(rdoCalc_CheckedChanged);

			base._vcManager_OnAfterHookEvents();
		}
		#endregion construct & initialize

		#region generic click and select
		public override void GenericClick(Control sender)
		{
			if (sender.Name == "btnVisit")
				SelectVisit();
			else if (sender.Name == "btnNewVisit")
				DisplayVisitForm();
			else if (sender.Name == "btnClear")
				ClearCosts();
		}

		private void DisplayVisitForm()
		{
			StringBuilder sb = new StringBuilder();
			FormProtocolVistOutPatient fv = new FormProtocolVistOutPatient();

			//need to create instance for bl			
			FormInfoBase fi = this._formMain.GetFormInfo(27, true);

			//check for permission
			Permission permission = Forms.FormSecurity.GetFormAccess(fi, LoginForm.ApplicationSecurity.ApplicationUser);
			if (permission == Permission.AccessDenied)
			{
				MessageBox.Show(this._form, "You do not have access rights for form: " + fi.Name, "Access Denied");
				return;
			}

			DataTable dt = Forms.Utils.GetTableSchema(fi.TableName, null);
			Hashtable ht = this._formMain.GetFormsConfigUserOptions();

			BLFormProtocolVisitOutPatientDialogImpl bl = new BLFormProtocolVisitOutPatientDialogImpl(this._formMain, fv, fi, dt, permission, ht);

			//create controller
			FormBaseControllerImpl ctlr = new FormBaseControllerImpl(fv, bl);
			if (!bl.Initialize())
			{
				sb.Append("Could not load form!");
				sb.Append(Environment.NewLine);
				sb.Append(Constants.NotifySupport);
				MessageBox.Show(this._form, sb.ToString(), "Loading Form Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			fv.Controller = ctlr;

			//bl.FormIcon = Icon.FromHandle(((Bitmap)this.imgL1.Images[fi.ImageIndex]).GetHicon());
			bl.GridView += new BusinessLogicEvents.BLGridViewEventHandler(this._formMain.OnGridView);
			bl.TableChange += new ctsu.BaseForms.BusinessLogicEvents.BLTableChangeEventHandler(this._formMain.OnTableChange);

			fv.ShowDialog(this._form);
			if (fv.DialogResult == DialogResult.OK)
			{
				VisitInfo vi = (VisitInfo)fv.DialogReturnObject;
				this.GetVisitData(vi);
				GetPatientData(vi.PatientID);
				GetProtocolData(vi.ProtocolID);
			}

		}

		private void SelectVisit()
		{
			StringBuilder sb = new StringBuilder();

			if (this._testDate.IsNullDate)
			{
				sb.Append("You must first select a date");
				MessageBox.Show(this._form, sb.ToString(), "Select Date", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				return;
			}
			Cursor.Current = Cursors.WaitCursor;
			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["AncillaryOutPatientVisit"];
			try
			{
				FormAncillaryAdmissionVisitSearch fs = new FormAncillaryAdmissionVisitSearch(si, this._testDate.Value);
				fs.Text = "Outpatient Visit Search";
				fs.ShowDialog(this._form);
				if (fs.DialogResult == DialogResult.OK)
				{
					VisitInfo vi = fs.SelectedVisitInfo;
					if (vi != null)
					{
						GetVisitData(vi);
						GetPatientData(vi.PatientID);
						GetProtocolData(vi.ProtocolID);
					}
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not display ancillary OutPatient visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void GetProtocolData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT p.ID, p.ProtocolNumber, " +
				" i.LastName + ', ' + i.FirstName AS Name " +
				" FROM Protocol p, ProtocolStaff ps, Investigator i " +
				" WHERE p.ID = " + id +
				" AND ps.ProtocolID = p.ID " +
				" AND ps.StaffTypeID = 1 " +
				" AND i.ID = ps.InvestigatorID"; ;

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (reader.Read())
				{
					this._protocol.Text = reader.GetInt32(0).ToString();
					//this._spid.Text = reader.GetInt32(1).ToString();
					this._protocolNumber.Text = reader.GetString(2);
					this._investigator.Text = reader.GetString(3);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve protocol information!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Protocol Information Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private void GetPatientData(int id)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT ID, MRN, LastName + ', ' + FirstName AS Name FROM Patient WHERE ID = " + id;

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (reader.Read())
				{
					this._patient.Text = reader.GetInt32(0).ToString();
					this._mrn.Text = reader.GetString(1);
					string name = "";
					if (!reader.IsDBNull(2))
						name = reader.GetString(2);
					this._patientName.Text = name;
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve patient!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Patient Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private void GetVisitData(VisitInfo vi)
		{
			StringBuilder sb = new StringBuilder();
			string sql = "SELECT p.VisitDate,c.Display " +
				" FROM ProtocolVisitOutPatient p, PCategory_L c WHERE p.ID = " + vi.ID +
				" AND p.PCategory=c.ID";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);
				if (reader.Read())
				{
					this._testDate.Value = vi.VisitDate;
					this._fcManager.BusinessLogic.Central_Validating(_testDate, new CancelEventArgs());
					this._visit.Text = vi.ID.ToString();
					this._fcManager.BusinessLogic.Central_Validating(_visit, new CancelEventArgs());
					this._visitDate.Text = reader.GetDateTime(0).ToString("MM/dd/yyyy");
					this._category.Text = reader.GetString(1);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve visit info!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Visit Info Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}
		#endregion generic click and select

		#region calculate charges
		private void _costCenter_SelectedIndexChanged(object sender, EventArgs e)
		{
			string message = "";

			if (this._formMode == EditMode.Load)
				return;
			if (_costCenter.SelectedIndex == -1)
			{
				this._rate.Text = "";
				return;
			}

			if (!GetAncilRate((int)_costCenter.SelectedValue, out message))
			{
				MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				this._rate.Text = "";
				_bIgnoreChargeEvents = true;
				if (this._rdoGross.Checked)
					this._charge.Text = "";
				else
					this._netCost.Text = "";
				_bIgnoreChargeEvents = false;
			}

			if (this._charge.Text.Length == 0 && this._netCost.Text.Length == 0)
				return;

			if (!CalculateCharge(out message))
			{
				MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
				_bIgnoreChargeEvents = true;
				if (this._rdoGross.Checked)
					this._charge.Text = "";
				else
					this._netCost.Text = "";
				_bIgnoreChargeEvents = false;
			}
		}

		public void ClearCosts()
		{
			_bIgnoreChargeEvents = true;
			this._charge.Text = "";
			this._netCost.Text = "";
			_bIgnoreChargeEvents = false;
		}

		public void rdoCalc_CheckedChanged(object sender, System.EventArgs e)
		{
			string message = "";
			if (_bIgnoreChargeEvents)
				return;
			if (_netCost.Text.Length == 0 && _charge.Text.Length == 0)
				return;
			if (!CalculateCharge(out message))
			{
				MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
			}
		}

		private void ChargeAndNetCost_Validating(object sender, System.ComponentModel.CancelEventArgs e)
		{
			string message = "";
			if (!CalculateCharge(out message))
			{
				MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
			}
		}

		private bool CalculateCharge(out string message)
		{
			message = "";
			StringBuilder sb = new StringBuilder();
			if (_costCenter.Text.Length == 0)
			{
				message = "You must select a cost center.";
				return false;
			}

			if (_rate.Text.Length == 0)
			{
				message = "You must select a cost center with a valid rate for this test date.";
				return false;
			}

			Decimal rate = Convert.ToDecimal(this._rate.Text);
			if (rate == 0)
			{
				MessageBox.Show(this._form, "Rate cannot be 0.", "Calculate Rate Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			Decimal rslt = 0;
			Decimal operand = 0;

			RadioButton rdoGross = (RadioButton)Forms.Utils.GetControlByName("rdoGross", this._form.Controls);
			try
			{
				if (rdoGross.Checked)
				{
					if (this._netCost.Text.Length == 0)
					{
						sb.Append("You must enter a net cost to calculate the gross charge.");
						sb.Append(Environment.NewLine);
						sb.Append("If you want to calculate net cost, select the radio button next to net cost.");
						if (this._charge.Text.Length == 0)
						{
							sb.Append(Environment.NewLine);
							sb.Append("And enter an amount for the gross charge.");
						}
						message = sb.ToString();
						return false;
					}
					operand = Convert.ToDecimal(this._netCost.Text);
					rslt = operand / rate;
					this._charge.Text = rslt.ToString();
				}
				else
				{
					if (this._charge.Text.Length == 0)
					{
						sb.Append("You must enter the gross charge to calculate the net cost.");
						sb.Append(Environment.NewLine);
						sb.Append("If you want to calculate the gross charge, select the radio button next to gross charge.");
						if (this._netCost.Text.Length == 0)
						{
							sb.Append(Environment.NewLine);
							sb.Append("And enter an amount for the net cost.");
						}
						message = sb.ToString();
						return false;
					}
					operand = Convert.ToDecimal(this._charge.Text);
					rslt = operand * rate;
					this._netCost.Text = rslt.ToString();
				}
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not calculate rate!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = sb.ToString();
				return false;
			}
		}

		private bool GetAncilRate(int id, out string message)
		{
			message = "";
			StringBuilder sb = new StringBuilder();
			if (this._testDate.IsNullDate)
			{
				sb.Append("Could not calculate the charge.");
				sb.Append(Environment.NewLine);
				sb.Append("You must first select a test date.");
				message = sb.ToString();
				return false;
			}

			string td = this._testDate.Value.ToShortDateString();

			string sql = "SELECT Rate FROM AncillaryRate " +
				" WHERE CostCenter=" + id +
				" AND (StartDate <='" + td + "'" +
				" AND EndDate >='" + td + "')";


			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);
				if (reader.Read())
				{
					decimal rate = reader.GetDecimal(0);
					this._rate.Text = rate.ToString("0.0000");
				}
				else
				{
					sb.Append("Could not calculate the charge.");
					sb.Append(Environment.NewLine);
					sb.Append("There was no rate found for the date: " + td + ".");
					message = sb.ToString();
					return false;
				}
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Error in retrieving cost center rate!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				message = sb.ToString();
				return false;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		#endregion calculat charges

		#region display data
		public override void DisplayData()
		{
			string message = "";

			_rdoNet.Checked = true;
			base.DisplayData();
			if (this._currentPrimaryID > 0)
			{
				if (!GetAncilRate((int)_costCenter.SelectedValue, out message))
				{
					MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					this._rate.Text = "";
					this._netCost.Text = "";
				}
				else
				{
					if (!CalculateCharge(out message))
					{
						MessageBox.Show(this._form, message, "Could Not Calculate Charge", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					}
				}
			}
			else
			{
				this._rate.Text = "";
				this._charge.Text = "";
				this._netCost.Text = "";
			}
			if (this._visit.Text.Length > 0)
			{
				int visitID = Convert.ToInt32(this._visit.Text);
				GetVisitPatientProtocolData(visitID);
			}
			else
				ClearNonFieldContextControls();

		}

		private void ClearNonFieldContextControls()
		{
			_testDate.IsNullDate = true;
			_visitDate.Text = "";
			_category.Text = "";
			_patient.Text = "";
			_mrn.Text = "";
			_patientName.Text = "";
			_protocol.Text = "";
			//_spid.Text = "";
			_protocolNumber.Text = "";
			_investigator.Text = "";
			_rate.Text = "";
			_netCost.Text = "";
		}

		protected override void ClearAllControls()
		{
			base.ClearAllControls();
			ClearNonFieldContextControls();
		}


		private void GetVisitPatientProtocolData(int id)
		{
			int patientID = -1;
			int protocolID = -1;

			StringBuilder sb = new StringBuilder();
			string sql = "SELECT p.VisitDate,p.DischargeDate,c.Display, " +
				" Patient,Protocol " +
				" FROM ProtocolVisitOutPatient p, PCategory_L c " +
				" WHERE p.ID = " + id +
				" AND p.PCategory=c.ID";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);
				if (reader.Read())
				{
					this._visit.Text = id.ToString();
					this._visitDate.Text = reader.GetDateTime(0).ToString("MM/dd/yyyy");
					this._category.Text = reader.GetString(2);
					patientID = reader.GetInt32(3);
					protocolID = reader.GetInt32(4);
				}
			}
			catch (Exception ex)
			{
				sb.Append("Could not retrieve visit info!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Retrieve Visit Info Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
				if (patientID > 0)
					this.GetPatientData(patientID);
				if (protocolID > 0)
					this.GetProtocolData(protocolID);
			}
		}
		#endregion display data

		#region carry
		public override void CarryNewClicked(object sender)
		{
			CarryAncillary ca = null;
			Hashtable ht = null;
			if (this._chkCarry.Checked)
			{
				//only do this if we have a visit id and a test date
				if (this._visit.Text.Length == 0)
					return;
				if (this._testDate.IsNullDate)
					return;

				ca = new CarryAncillary();
				ca.VisitID = Convert.ToInt32(this._visit.Text);
				ca.AncillaryID = this._currentPrimaryID;
				ca.TestDate = this._testDate.Value;
				ca.Reference = this._reference.Text;
				ca.Source = this._ancillarySource.SelectedIndex;
				if (_rdoNet.Checked)
					ca.ChargeType = CalculateType.Net;

				ht = this._formMain.CarryNew;
				if (ht.Contains(this._formInfo.ID))
					ht[this._formInfo.ID] = ca;
				else
					ht.Add(this._formInfo.ID, ca);
			}
			else
				ClearCarryData();
		}

		protected override void ClearCarryData()
		{
			Hashtable ht = this._formMain.CarryNew;
			if (ht.Contains(this._formInfo.ID))
				ht.Remove(this._formInfo.ID);
		}

		protected override void GetCarryData()
		{
			Hashtable ht = null;
			CarryAncillary ca = null;
			if (this._chkCarry.Checked)
			{
				ht = this._formMain.CarryNew;
				if (ht.Contains(this._formInfo.ID))
				{
					ca = (CarryAncillary)ht[this._formInfo.ID];
					this.GetVisitPatientProtocolData(ca.VisitID);
					this._testDate.Value = ca.TestDate;
					this._ancillarySource.SelectedIndex = ca.Source;
					this._reference.Text = ca.Reference;

					_bIgnoreChargeEvents = true;
					if (ca.ChargeType == CalculateType.Gross)
						_rdoGross.Checked = true;
					_bIgnoreChargeEvents = false;
				}
			}
		}
		#endregion carry

		#region validate
		private bool VerifyCharge(Control ctl)
		{
			string message = "";
			FieldContext fc = (FieldContext)ctl.Tag;

			if (Forms.Utils.IsMissingValue(ctl))
			{
				if (fc.IsRequired)
				{
					fc.ErrorMessage = Constants.ValidErrorRequiredEmpty;
					return false;
				}
			}

			if (!CalculateCharge(out message))
			{
				fc.ErrorMessage = Constants.ValidErrorRequiredEmpty;
				return false;
			}
			return true;
		}

		private bool VerifyRate(Control ctl)
		{
			string message = "";
			FieldContext fc = (FieldContext)ctl.Tag;

			//tests for required if empty
			if (!this.VerifyInt(ctl))
				return false;

			if (!GetAncilRate((int)_costCenter.SelectedValue, out message))
			{
				fc.ErrorMessage = message;
				return false;
			}
			return true;
		}

		private bool VerifyVisit(Control ctl)
		{
			StringBuilder sb = new StringBuilder();
			FieldContext fc = (FieldContext)ctl.Tag;

			//check for missing visit
			if (Forms.Utils.IsMissingValue(ctl))
			{
				if (fc.IsRequired)
				{
					fc.ErrorMessage = Constants.ValidErrorRequiredEmpty;
					return false;
				}
			}
			int visitID = Convert.ToInt32(ctl.Text);

			//check for missing patient
			if (Forms.Utils.IsMissingValue(this._patient))
			{
				fc.ErrorMessage = "Patient is Missing";
				return false;
			}
			int patientID = Convert.ToInt32(this._patient.Text);

			//check for missing protocol
			if (Forms.Utils.IsMissingValue(this._protocol))
			{
				fc.ErrorMessage = "Protocol is missing";
				return false;
			}
			int protocolID = Convert.ToInt32(this._protocol.Text);

			//verify matching visit
			string sql = "SELECT ID FROM ProtocolVisitOutPatient " +
				" WHERE ID=" + visitID +
				" AND Patient=" + patientID +
				" AND Protocol=" + protocolID +
				" AND VisitDate = '" + this._testDate.Value.ToShortDateString() + "'";

			//SqlConnection conn = LoginForm.GetSqlConnection();
			IDataReader reader = null;
			try
			{
				reader = DataAccess.GetDataReader(sql);

				if (!reader.Read())
				{
					fc.ErrorMessage = "Could not find matching visit.\nYou must either choose a matching vist or enter a new visit.";
					return false;
				}
			}
			catch (Exception ex)
			{
				sb.Append("Error in trying to match OutPatient visit!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "OutPatient Visit Match Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			finally
			{
				if (reader != null)
				{
					if (!reader.IsClosed)
						reader.Close();
				}
				//if(conn != null)
				//    conn.Dispose();
			}
			return true;
		}
		#endregion validate

		#region search
		public override void Search(object sender)
		{
			Control ctl = (Control)sender;

			ctl.Enabled = false;
			SelectAncillaryDlg sad = new SelectAncillaryDlg(this._formInfo.ID);
			sad.Text = this._formInfo.Name + " Search";
			sad.ShowDialog(this._formMain);
			switch (sad.SearchChoice)
			{
				case -1:
					break;
				case 0:
					SelectByStandard();
					break;
				case 1:
					SelectByVisits();
					break;
				case 2:
					SelectByPatient();
					break;
				case 3:
					SelectByProtocol();
					break;
				case 4:
					SelectByInvestigator();
					break;
			}

			ctl.Enabled = true;
		}

		private void SelectByInvestigator()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Investigator"];
			_searchType = SearchTypes.Investigator;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private void SelectByProtocol()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Protocol"];
			_searchType = SearchTypes.Protocol;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display protocol seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByPatient()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["Patient"];
			_searchType = SearchTypes.Patient;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display patient seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByVisits()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["VisitOutPatient"];
			_searchType = SearchTypes.OutpatientVisits;
			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Controller.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(scr_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				fs.Owner = this._form;
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display Outpatient Visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}

		}

		private void SelectByStandard()
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchInfo si = (SearchInfo)this._formInfo.SearchFormInfo["AncillaryOutPatient"];

			try
			{
				FormSearchBase fs = (FormSearchBase)SearchUtils.GetSearchDialog(si);
				fs.Owner = this._form;
				fs.Controller.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(sc_ItemSelected);
				fs.Closing += new CancelEventHandler(fs_Closing);
				IsSearchVisible = true;
				fs.Show();
			}
			catch (Exception ex)
			{
				sb.Append("Could not display out patient visit seach dialog!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Display Search Dialog Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
		}

		private int SelectFromResults(int id, string recordType, string searchBy, string searchResultKey)
		{
			StringBuilder sb = new StringBuilder();
			Cursor.Current = Cursors.WaitCursor;

			SearchResultInfo si = (SearchResultInfo)this._formInfo.SearchResultInfo[searchResultKey];
			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				//first see if there are any visits for this patient
				string sql = si.SqlCommand + id;

				DataSet ds = DataAccess.GetDataSet(sql);
				DataTable dt = ds.Tables[0];
				if (dt.Rows.Count == 0)
				{
					MessageBox.Show("There are no " + recordType + " for " + searchBy + " id: " + id, "No " + recordType + " Found", MessageBoxButtons.OK, MessageBoxIcon.Information);
					return 0;
				}
				SearchUtils.SetColumnMeta(dt, si);
				FormSearchResultsBase fsr = (FormSearchResultsBase)SearchUtils.GetSearchResultsDialog(si, dt);
				fsr.Text = searchBy + " Search";
				fsr.Controller.BusinessLogic.ItemSelected += new ctsu.BaseForms.BusinessLogicEvents.BLSelectedItemEventHandler(BusinessLogic_ItemSelected);
				fsr.Closing += new CancelEventHandler(fsr_Closing);
				fsr.Owner = this._form;
				fsr.Show();
				return 1;
			}
			catch (Exception ex)
			{
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				sb.Append("Could not retrieve select results.");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				MessageBox.Show(this._form, sb.ToString(), "Select Results Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return 0;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		private void scr_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			string recordType = "";
			string searchBy = "";
			string searchResultsKey = "";

			switch (this._searchType)
			{
				case SearchTypes.OutpatientVisits:
					recordType = "Out-Patient Ancillaries";
					searchBy = "Out Patient Visit";
					searchResultsKey = "OutPatientVisitOutPatientAncillary";
					break;
				case SearchTypes.Investigator:
					recordType = "Out Patient Ancillaries";
					searchBy = "Protocol";
					searchResultsKey = "ProtocolOutPatientAncillary";
					break;
				case SearchTypes.Patient:
					recordType = "Out Patient Ancillaries";
					searchBy = "Patient";
					searchResultsKey = "PatientOutPatientAncillary";
					break;
				case SearchTypes.Protocol:
					recordType = "Out Patient Ancillaries";
					searchBy = "Protocol";
					searchResultsKey = "ProtocolOutPatientAncillary";
					break;
			}
			if (e.ID > 0)
				SelectFromResults(e.ID, recordType, searchBy, searchResultsKey);
		}

		private void BusinessLogic_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			if (e.ID > 0)
			{
				if (this.GetData(e.ID))
				{
					if (this.FormMode == EditMode.Load)
						SetFormMode(EditMode.Read);
				}
			}
		}

		private void fsr_Closing(object sender, CancelEventArgs e)
		{

		}

		private void sc_ItemSelected(object sender, BLReturnIDEventArgs e)
		{
			if (e.ID > 0)
			{
				Console.WriteLine("Selected ID: " + e.ID.ToString());
				if (GetData(e.ID))
				{
					if (this.FormMode == EditMode.Load)
						SetFormMode(EditMode.Read);
				}
			}
			else
				Console.WriteLine("ID: " + e.ID);
		}

		private void fs_Closing(object sender, CancelEventArgs e)
		{
			IsSearchVisible = false;
			this._form.btnSearch.Enabled = true;
		}
		#endregion search

		public override bool Remove()
		{
			StringBuilder sb = new StringBuilder();
			sb.Append("Press 'Yes' to confirm the removal of OutPatient Ancillary ID: " + this._currentPrimaryID.ToString());
			sb.Append(Environment.NewLine);
			sb.Append("or press 'No' to cancel.");
			if (MessageBox.Show(this._form, sb.ToString(), "Confirm Ancillary Removal", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No)
				return false;

			sb.Remove(0, sb.Length);

			//this is used as a parameter for table grid display
			DbTableChange tableChange = DbTableChange.Update;

			string sql = "DELETE FROM AncillaryOutPatient WHERE ID=" + this._currentPrimaryID;

			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				int i = DataAccess.ExecuteNonQuery(CommandType.Text, sql);
				if (i == 1)
				{
					sb.Append("Outpatient Ancillary ID: " + this._currentPrimaryID.ToString() + " was deleted.");
					this._fcManager.CurrentRow.Delete();
					this.ResetToOriginal();
					MessageBox.Show(this._form, sb.ToString(), "Confirm Ancillary Removal", MessageBoxButtons.OK, MessageBoxIcon.Information);

					BLTableChangeAdvEventArgs args = new BLTableChangeAdvEventArgs(this._formInfo.TableName, tableChange, this._currentPrimaryID - 1);

					this.FireTableChange(args);
				}
				else
				{
					sb.Append("Outpatient Ancillary ID: " + this._currentPrimaryID.ToString() + " was not deleted.");
					sb.Append(Environment.NewLine);
					sb.Append(Shared.Constants.NotifySupportImmediate);
					MessageBox.Show(this._form, sb.ToString(), "Ancillary Removal", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				}
				return true;
			}
			catch (Exception ex)
			{
				sb.Append("Could not delete outpatient ancillary!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Delete Ancillary Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		protected override bool CheckDuplicate()
		{
			StringBuilder sb = new StringBuilder();
			ComboBox cboCenter = (ComboBox)Forms.Utils.GetControlByName("CostCenter", this._form.Controls);
			//verify all should make sure there are valid values
			int visit = Convert.ToInt32(_visit.Text);
			int costCenter = (int)cboCenter.SelectedValue;
			decimal charge = Convert.ToDecimal(_charge.Text);
			string reference = this._reference.Text;

			string sql = "SELECT Count(ID) FROM AncillaryOutPatient " +
				" WHERE Visit=" + visit +
				" AND TestDate ='" + this._testDate.Value.ToShortDateString() + "'" +
				" AND CostCenter=" + costCenter +
				" AND Charge=" + charge +
				" AND Reference='" + reference + "'";


			//SqlConnection conn = LoginForm.GetSqlConnection();
			try
			{
				int i = (int)DataAccess.GetScalarObject(CommandType.Text, sql);
				if (i > 0)
				{
					sb.Append("There is another ancillary record with the same test date, visit, cost center and charge.");
					sb.Append(Environment.NewLine);
					sb.Append("Can't save duplicate ancillary.");
					MessageBox.Show(this._form, sb.ToString(), "Duplicate Ancillary", MessageBoxButtons.OK, MessageBoxIcon.Stop);
					return true;
				}
				return false;
			}
			catch (Exception ex)
			{
				sb.Append("Could not check for duplicates!");
				sb.Append(Environment.NewLine);
				sb.Append("Error message: " + ex.Message);
				//bool b = ////ExceptionPolicy.HandleException(ex, "Exception Policy");
				MessageBox.Show(this._form, sb.ToString(), "Check Duplicates Failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return true;
			}
			finally
			{
				//if(conn != null)
				//    conn.Dispose();
			}
		}

		protected override void SetControlsEnabled(bool enable)
		{
			base.SetControlsEnabled(enable);
			_testDate.Enabled = enable;
			_visit.Enabled = enable;
			_visitDate.Enabled = enable;
			_category.Enabled = enable;
			_patient.Enabled = enable;
			_mrn.Enabled = enable;
			_patientName.Enabled = enable;
			_btnPatient.Enabled = enable;
			_btnProtocol.Enabled = enable;
			_btnVisit.Enabled = enable;
			_protocol.Enabled = enable;
			//_spid.Enabled = enable;
			_protocolNumber.Enabled = enable;
			_investigator.Enabled = enable;
			_netCost.Enabled = enable;
			_rdoGross.Enabled = enable;
			_rdoNet.Enabled = enable;
		}
	}
}
